Add support for the ioport_permission dom0 op to xend and xm
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Mon, 7 Nov 2005 11:05:15 +0000 (12:05 +0100)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Mon, 7 Nov 2005 11:05:15 +0000 (12:05 +0100)
xm now accepts a parameter 'ioports' that accepts a hex ioport
or ioport range, in the form 02f8[-02ff]

Signed-off-by: Jody Belka <knew (at) pimb (dot) org>
tools/python/xen/xend/XendDomain.py
tools/python/xen/xend/XendDomainInfo.py
tools/python/xen/xend/server/iopif.py [new file with mode: 0644]
tools/python/xen/xm/create.py

index 3c0532645c28b9fb7099b98384ca48ad380ef3ad..a429852788c7be0a18d782647aa889ba042fec0c 100644 (file)
@@ -492,6 +492,40 @@ class XendDomain:
         except Exception, ex:
             raise XendError(str(ex))
 
+    def domain_ioport_range_enable(self, domid, first, last):
+        """Enable access to a range of IO ports for a domain
+
+        @param first: first IO port
+        @param last: last IO port
+        @return: 0 on success, -1 on error
+        """
+        dominfo = self.domain_lookup(domid)
+        nr_ports = last - first + 1
+        try:
+            return xc.domain_ioport_permission(dominfo.getDomid(),
+                                               first_port = first,
+                                               nr_ports = nr_ports,
+                                               allow_access = 1)
+        except Exception, ex:
+            raise XendError(str(ex))
+
+    def domain_ioport_range_disable(self, domid, first, last):
+        """Disable access to a range of IO ports for a domain
+
+        @param first: first IO port
+        @param last: last IO port
+        @return: 0 on success, -1 on error
+        """
+        dominfo = self.domain_lookup(domid)
+        nr_ports = last - first + 1
+        try:
+            return xc.domain_ioport_permission(dominfo.getDomid(),
+                                               first_port = first,
+                                               nr_ports = nr_ports,
+                                               allow_access = 0)
+        except Exception, ex:
+            raise XendError(str(ex))
+
 
 def instance():
     """Singleton constructor. Use this instead of the class constructor.
index 7e2199ec6e4be58d926f128f87825d80cbbd6fad..f8ccc0d14ef92eb7aba3b372cc0cc6bacdb998cf 100644 (file)
@@ -1400,9 +1400,10 @@ def addControllerClass(device_class, cls):
     controllerClasses[device_class] = cls
 
 
-from xen.xend.server import blkif, netif, tpmif, pciif, usbif
+from xen.xend.server import blkif, netif, tpmif, pciif, iopif, usbif
 addControllerClass('vbd',  blkif.BlkifController)
 addControllerClass('vif',  netif.NetifController)
 addControllerClass('vtpm', tpmif.TPMifController)
 addControllerClass('pci',  pciif.PciController)
+addControllerClass('ioports', iopif.IOPortsController)
 addControllerClass('usb',  usbif.UsbifController)
diff --git a/tools/python/xen/xend/server/iopif.py b/tools/python/xen/xend/server/iopif.py
new file mode 100644 (file)
index 0000000..25f05d0
--- /dev/null
@@ -0,0 +1,86 @@
+#============================================================================
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of version 2.1 of the GNU Lesser General Public
+# License as published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+#============================================================================
+# Copyright (C) 2004, 2005 Mike Wray <mike.wray@hp.com>
+# Copyright (C) 2005 XenSource Ltd
+# Copyright (C) 2005 Jody Belka
+#============================================================================
+
+
+import types
+
+import xen.lowlevel.xc;
+
+from xen.xend import sxp
+from xen.xend.XendError import VmError
+
+from xen.xend.server.DevController import DevController
+
+
+xc = xen.lowlevel.xc.new()
+
+
+def parse_ioport(val):
+    """Parse an i/o port field.
+    """
+    if isinstance(val, types.StringType):
+        radix = 10
+        if val.startswith('0x') or val.startswith('0X'):
+            radix = 16
+        v = int(val, radix)
+    else:
+        v = val
+    return v
+
+
+class IOPortsController(DevController):
+
+    def __init__(self, vm):
+        DevController.__init__(self, vm)
+
+
+    def getDeviceDetails(self, config):
+        """@see DevController.getDeviceDetails"""
+
+        def get_param(field):
+            try:
+                val = sxp.child_value(config, field)
+
+                if not val:
+                    raise VmError('ioports: Missing %s config setting' % field)
+
+                return parse_ioport(val)
+            except:
+                raise VmError('ioports: Invalid config setting %s: %s' %
+                              (field, val))
+       
+        io_from = get_param('from')
+        io_to = get_param('to') 
+
+        if io_to < io_from or io_to >= 65536:
+            raise VmError('ioports: Invalid i/o range: %s - %s' %
+                          (io_from, io_to))
+
+        rc = xc.domain_ioport_permission(dom          = self.getDomid(),
+                                         first_port   = io_from,
+                                         nr_ports     = io_to - io_from + 1,
+                                         allow_access = True)
+
+        if rc < 0:
+            #todo non-fatal
+            raise VmError(
+                'ioports: Failed to configure legacy i/o range: %s - %s' %
+                (io_from, io_to))
+
+        return (dev, {}, {})
index d844b2044c0a4514cd740f69712c04988abfe89e..c73d66c2f933f94766a55a36d666a741dfc49686 100644 (file)
@@ -241,6 +241,12 @@ gopts.var('pci', val='BUS,DEV,FUNC',
          For example '-pci c0,02,1a'.
          The option may be repeated to add more than one pci device.""")
 
+gopts.var('ioports', val='FROM[-TO]',
+          fn=append_value, default=[],
+          use="""Add a legacy I/O range to a domain, using given params (in hex).
+         For example '-ioports 02f8-02ff'.
+         The option may be repeated to add more than one i/o range.""")
+
 gopts.var('usb', val='PATH',
           fn=append_value, default=[],
           use="""Add a physical USB port to a domain, as specified by the path
@@ -439,6 +445,13 @@ def configure_pci(config_devs, vals):
         config_pci = ['pci', ['bus', bus], ['dev', dev], ['func', func]]
         config_devs.append(['device', config_pci])
 
+def configure_ioports(config_devs, vals):
+    """Create the config for legacy i/o ranges.
+    """
+    for (io_from, io_to) in vals.ioports:
+        config_ioports = ['ioports', ['from', io_from], ['to', io_to]]
+        config_devs.append(['device', config_ioports])
+
 def configure_usb(config_devs, vals):
     for path in vals.usb:
         config_usb = ['usb', ['path', path]]
@@ -611,6 +624,7 @@ def make_config(vals):
     config_devs = []
     configure_disks(config_devs, vals)
     configure_pci(config_devs, vals)
+    configure_ioports(config_devs, vals)
     configure_vifs(config_devs, vals)
     configure_usb(config_devs, vals)
     configure_vtpm(config_devs, vals)
@@ -645,6 +659,20 @@ def preprocess_pci(vals):
         pci.append(hexd)
     vals.pci = pci
 
+def preprocess_ioports(vals):
+    if not vals.ioports: return
+    ioports = []
+    for v in vals.ioports:
+        d = v.split('-')
+        if len(d) < 1 || len(d) > 2:
+            err('Invalid i/o port range specifier: ' + v)
+        if len(d) == 1:
+            d.append(d[0])
+        # Components are in hex: add hex specifier.
+        hexd = map(lambda v: '0x'+v, d)
+        ioports.append(hexd)
+    vals.ioports = ioports
+        
 def preprocess_vifs(vals):
     if not vals.vif: return
     vifs = []
@@ -777,6 +805,7 @@ def preprocess(vals):
         err("No kernel specified")
     preprocess_disk(vals)
     preprocess_pci(vals)
+    preprocess_ioports(vals)
     preprocess_vifs(vals)
     preprocess_ip(vals)
     preprocess_nfs(vals)